package zero.tech.games.dn.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.stereotype.Service;

import zero.tech.core.data.Resp;
import zero.tech.core.work.WorkManager;
import zero.tech.games.common.BigCalSource;
import zero.tech.games.common.Code;
import zero.tech.games.dn.data.DnConfig;
import zero.tech.games.dn.data.DnGameBase;
import zero.tech.games.dn.data.DnRoomCache;
import zero.tech.games.dn.data.DnRoomStatus;
import zero.tech.games.dn.data.DnSmallPanel;
import zero.tech.games.dn.data.DnTimer;
import zero.tech.games.dn.data.consts.DNCMD;
import zero.tech.games.dn.data.entity.Card;
import zero.tech.games.dn.data.entity.DnMultiple;
import zero.tech.games.dn.data.entity.DnOut;
import zero.tech.games.dn.data.entity.PlayerData;
import zero.tech.games.dn.data.entity.PlayerSmallCal;
import zero.tech.games.dn.data.entity.SetcardsPanel;
import zero.tech.games.dn.data.notify.NotifyBeginQiangzhuang;
import zero.tech.games.dn.service.api.IDnService;
import zero.tech.games.dn.util.CardUtil;
import zero.tech.games.dn.util.PackageUtil;
import zero.tech.games.dn.util.PlaybackUtil;
import zero.tech.games.dn.util.RoomUtil;
import zero.tech.games.dn.work.sync.GameOverCalculateSyncWork;
import zero.tech.games.logic.common.Room;
import zero.tech.games.logic.common.RoomCache;
import zero.tech.games.logic.data.RoomStatus;
import zero.tech.games.logic.data.res.ResReconnet;
import zero.tech.games.logic.util.LogicUtil;
import zero.tech.games.logic.util.PckUtil;
import zero.tech.wsnet.controller.LogicController;
import zero.tech.wsnet.data.Message;
@Service
public class DnServiceImpl implements IDnService{

	@Override
	public ResReconnet roomReconnect(Room room, LogicController online) {
		ResReconnet resReconnet=PackageUtil.packageResDnReconnect(room,online);
		return resReconnet;
	}

	@Override
	public void roomTimer(Room room) {
		long now=System.currentTimeMillis();
		int room_status=room.getRoom_status();
		DnTimer dnTimer = (DnTimer) room.getTimer();
		DnConfig dnConfig = (DnConfig) room.getGameConfig();
		if(room_status==DnRoomStatus.DEFAULT) {
			RoomUtil.checkGameStart(room);
		}else if(room_status==DnRoomStatus.QIANGZHUANG) {
			int qiangzhuang_timer=dnConfig.getQiangzhuang_timer();
			long lastBeginQiangzhuangTimer=dnTimer.lastBeginQiangzhuangTimer;
			if(qiangzhuang_timer!=0&&now-lastBeginQiangzhuangTimer>=qiangzhuang_timer*1000) {
				//自动为没有抢庄的玩家抢庄
				autoQiangzhuang(room);
			}
			RoomUtil.checkQiangzhuangToYazhu(room);
		}else if(room_status==DnRoomStatus.YAZHU){
			int yazhu_timer=dnConfig.getYazhu_timer();
			long lastBeginYazhuTimer=dnTimer.lastBeginYazhuTimer;
			if(yazhu_timer!=0&&now-lastBeginYazhuTimer>=yazhu_timer*1000) {
				//自动为没有压注的玩家压注
				autoYazhu(room);
			}
			RoomUtil.checkYazhuToLiangpai(room);
		}else if(room_status==DnRoomStatus.LIANGPAI){
			int liangpai_timer=dnConfig.getLiangpai_timer();
			long lastBeginLiangpaiTimer=dnTimer.lastBeginLiangpaiTimer;
			if(liangpai_timer!=0&&now-lastBeginLiangpaiTimer>=liangpai_timer*1000) {
				//自动为没有亮牌的玩家亮牌
				autoLiangpai(room);
			}
			RoomUtil.checkLiangpaiToGameOver(room);
		}else if(room_status==DnRoomStatus.WAIT_NEXT_ROUND){
			RoomUtil.checkGameStart(room);
		}else if(room_status==DnRoomStatus.CALCULATING) {
			
		}
	}

	private void autoLiangpai(Room room) {
		DnGameBase dnGameBase = (DnGameBase) room.getGameBase();
		for(PlayerData playerData :dnGameBase.getPlayers().values()) {
			if(playerData.getLiangpai()==null||!playerData.getLiangpai()) {
				int uid=playerData.getUid();
				LogicController controller=room.getControllersWithoutWatcherAndTaotai().get(uid);
				reqLiangpai(room, controller);
			}
		}
	}

	private void autoYazhu(Room room) {
		DnGameBase dnGameBase = (DnGameBase) room.getGameBase();
		int banker_uid=dnGameBase.getBanker_uid();
		for(PlayerData playerData :dnGameBase.getPlayers().values()) {
			int uid=playerData.getUid();
			if(uid!=banker_uid) {
				LogicController controller=room.getControllersWithoutWatcherAndTaotai().get(uid);
				reqYazhu(room, controller, 1);
			}
		}
	}

	private void autoQiangzhuang(Room room) {
		DnGameBase dnGameBase = (DnGameBase) room.getGameBase();
		for(PlayerData playerData :dnGameBase.getPlayers().values()) {
			if(playerData.getQiangzhuang_multiple()==null) {
				int uid=playerData.getUid();
				LogicController controller=room.getControllersWithoutWatcherAndTaotai().get(uid);
				reqQiangzhuang(room, controller, 0);
			}
		}
	}

	@Override
	public void gameStart(Room room) {
		initRoomBasic(room);
		initHandCards(room);
		initSmallPanel(room);
		notifyGameStart(room);		
	}

	private void notifyGameStart(Room room) {
		LogicUtil.broadRoomAllControllersInclude(room, Message.build(DNCMD.NOTIFY_GAME_START, Resp.build(Code.OK, "通知游戏开始",PackageUtil.packageNotifyGameStart(room))));
		DnConfig dnConfig = (DnConfig) room.getGameConfig();
		DnRoomCache dnRoomCache = (DnRoomCache) room.getRoomCache();
		DnGameBase dnGameBase = (DnGameBase) room.getGameBase();
		if(dnConfig.getZhuang_mode()==0) {
			//抢庄斗牛,通知开始抢庄
			Map<Integer,PlayerData> playerDatas=dnGameBase.getPlayers();
			for(LogicController logicController:room.getControllersWithoutWatcherAndTaotai().values()) {
				PlayerData playerData =playerDatas.get(logicController.getId());
				//计算抢庄倍数
				int qiangzhuang_max_multiple=RoomUtil.calQiangzhuangMaxMultiple(room,logicController);
				playerData.setQiangzhuang_max_multiple(qiangzhuang_max_multiple);
				NotifyBeginQiangzhuang notifyBeginQiangzhuang=PackageUtil.packageNotifyBeginQiangzhuang(room,playerData);
				logicController.getWebClient().sendMessage(Message.build(DNCMD.NOTIFY_BEGIN_QIANGZHUANG, Resp.build(Code.OK, "通知开始抢庄",notifyBeginQiangzhuang)));
			}		
			for(LogicController logicController:room.getWatcherAndTaotai().values()) {
				NotifyBeginQiangzhuang notifyBeginQiangzhuang=PackageUtil.packageNotifyBeginQiangzhuang(room,null);
				logicController.getWebClient().sendMessage(Message.build(DNCMD.NOTIFY_BEGIN_QIANGZHUANG, Resp.build(Code.OK, "通知游戏开始",notifyBeginQiangzhuang)));
			}	
		}else if(dnConfig.getZhuang_mode()==1) {
			//轮庄
			Integer last_banker_uid=dnRoomCache.getLast_banker_uid();
			if(last_banker_uid==null) {
				RoomUtil.checkLunzhuangToYazhu(room,null);
			}else {
				Integer banker_uid=LogicUtil.getNextPosByUid(room,last_banker_uid);
				RoomUtil.checkLunzhuangToYazhu(room,banker_uid);
			}
		}
	}

	private void initSmallPanel(Room room) {
		DnRoomCache dnRoomCache = (DnRoomCache) room.getRoomCache();
		int room_times=room.getRoom_times();
		String room_id=room.getRoom_id();
		String configStr=room.getConfigStr();
		DnSmallPanel dnSmallPanel = new DnSmallPanel();
		dnSmallPanel.setRoom_id(room_id);
		dnSmallPanel.setConfigStr(configStr);		
		dnRoomCache.getSmallPanels().put(room_times, dnSmallPanel);		
	}

	private void initHandCards(Room room) {
		DnRoomCache dnRoomCache = (DnRoomCache) room.getRoomCache();
		DnGameBase dnGameBase =(DnGameBase) room.getGameBase();
		DnConfig dnConfig = (DnConfig) room.getGameConfig();
		int mingpai=dnConfig.getMingpai();
		Map<Integer, LogicController> controllers=room.getControllersWithoutWatcherAndTaotai();
		int size=controllers.size();
		List<List<Card>> tmps=new ArrayList<>();
		List<Card> deck=new ArrayList<>();
		deck.addAll(CardUtil.deckWithoutJoker());
		Collections.shuffle(deck);
		SetcardsPanel setcardsPanel = dnRoomCache.getSetcardsPanel();
		Map<Integer, List<Integer>> setsmap =setcardsPanel.getSetsmap();
		List<Integer> uids=new ArrayList<>();
		uids.addAll(controllers.keySet());
		Collections.shuffle(uids);
		if(!setsmap.isEmpty()) {
			//配牌器发牌
			List<Integer> setcard_uids=new ArrayList<>();
			for(Entry<Integer,List<Integer>> entry:setsmap.entrySet()) {
				int uid=entry.getKey();
				if(uids.contains(uid)){
					List<Integer> cardIds=entry.getValue();
					List<Card> hands=CardUtil.findCardsByCardId(deck,cardIds);
					
					List<Card> shows =new ArrayList<>();
					List<Card> hides=new ArrayList<>();
					if(mingpai==1) {
						shows.addAll(hands.subList(0, 3));
						hides.addAll(hands.subList(3, 5));
					}else {
						shows.addAll(hands.subList(0, 4));
						hides.addAll(hands.subList(4, 5));
					}
					List<Card> list=new ArrayList<>();
					list.addAll(shows);
					list.addAll(hides);
					DnOut dnOut=CardUtil.calDnOut(list,dnConfig);
					PlayerData playerData=new PlayerData(uid,shows,hides,dnOut);
					dnGameBase.getPlayers().put(uid,playerData);
					
					deck.removeAll(hands);
					setcard_uids.add(uid);
				}
			}
			uids.removeAll(setcard_uids);
			
			for(int i=0;i<uids.size();i++) {
				List<Card> hands=new ArrayList<Card>();
				hands.addAll(deck.subList(i*5, i*5+5));
				tmps.add(hands);
			}
			int index=0;
			for(int i=0;i<uids.size();i++) {
				int uid=uids.get(i);
				List<Card> hands=tmps.get(index++);
				List<Card> shows =new ArrayList<>();
				List<Card> hides=new ArrayList<>();
				if(mingpai==1) {
					shows.addAll(hands.subList(0, 3));
					hides.addAll(hands.subList(3, 5));
				}else {
					shows.addAll(hands.subList(0, 4));
					hides.addAll(hands.subList(4, 5));
				}
				List<Card> list=new ArrayList<>();
				list.addAll(shows);
				list.addAll(hides);
				DnOut dnOut=CardUtil.calDnOut(list,dnConfig);
				PlayerData playerData=new PlayerData(uid,shows,hides,dnOut);
				dnGameBase.getPlayers().put(uid,playerData);
			}
			
			dnRoomCache.setSetcardsPanel(new SetcardsPanel());//清除设置面板
		}else {
			
			//随机发牌
			for(int i=0;i<size;i++) {
				List<Card> hands=new ArrayList<Card>();
				hands.addAll(deck.subList(i*5, i*5+5));
				tmps.add(hands);
			}
			int index=0;
			for(LogicController controller:controllers.values()) {
				int uid=controller.getId();
				List<Card> hands=tmps.get(index++);
				List<Card> shows =new ArrayList<>();
				List<Card> hides=new ArrayList<>();
				if(mingpai==1) {
					shows.addAll(hands.subList(0, 3));
					hides.addAll(hands.subList(3, 5));
				}else {
					shows.addAll(hands.subList(0, 4));
					hides.addAll(hands.subList(4, 5));
				}
				List<Card> list=new ArrayList<>();
				list.addAll(shows);
				list.addAll(hides);
				DnOut dnOut=CardUtil.calDnOut(list,dnConfig);
				PlayerData playerData=new PlayerData(uid,shows,hides,dnOut);
				dnGameBase.getPlayers().put(uid,playerData);
			}
		}
	}

	private void initRoomBasic(Room room) {
		DnTimer dnTimer=(DnTimer) room.getTimer();
		room.setRoom_status(DnRoomStatus.QIANGZHUANG);
		room.setRoom_times(room.getRoom_times()+1);
		dnTimer.lastBeginQiangzhuangTimer=System.currentTimeMillis();		
	}

	@Override
	public void changeToYazhu(Room room) {
		DnTimer dnTimer=(DnTimer) room.getTimer();
		room.setRoom_status(DnRoomStatus.YAZHU);
		dnTimer.lastBeginYazhuTimer=System.currentTimeMillis();
		DnGameBase dnGameBase=(DnGameBase) room.getGameBase();
		Map<Integer,PlayerData> playerDatas=dnGameBase.getPlayers();
		DnConfig dnConfig = (DnConfig) room.getGameConfig();
		int yazhu_timer=dnConfig.getYazhu_timer();
		int banker_uid=dnGameBase.getBanker_uid();
		for(LogicController logicController:room.getControllersWithoutWatcherAndTaotai().values()) {
			PlayerData playerData = playerDatas.get(logicController.getId());
			//计算最大压注倍数
			int yazhu_max_multiple=RoomUtil.calYazhuMaxMultiple(room,logicController);
			playerData.setYazhu_max_multiple(yazhu_max_multiple);
			logicController.getWebClient().sendMessage(Message.build(DNCMD.NOTIFY_BEGIN_YAZHU,Resp.build(Code.OK, "开始压注",PackageUtil.packageNotifyBeginYazhu(banker_uid,yazhu_timer,yazhu_max_multiple))));
		}
		for(LogicController logicController:room.getWatcherAndTaotai().values()) {
			logicController.getWebClient().sendMessage(Message.build(DNCMD.NOTIFY_BEGIN_YAZHU,Resp.build(Code.OK, "开始压注",PackageUtil.packageNotifyBeginYazhu(banker_uid,yazhu_timer,null))));
		}
	}

	@Override
	public void changeToLiangpai(Room room) {
		DnTimer dnTimer=(DnTimer) room.getTimer();
		room.setRoom_status(DnRoomStatus.LIANGPAI);
		dnTimer.lastBeginLiangpaiTimer=System.currentTimeMillis();		
		DnConfig dnConfig = (DnConfig) room.getGameConfig();
		int liangpai_timer=dnConfig.getLiangpai_timer();
		Message msg=Message.build(DNCMD.NOTIFY_BEGIN_LIANGPAI,Resp.build(Code.OK, "开始亮牌",PackageUtil.packageNotifyBeginLiangpai(liangpai_timer)));
		LogicUtil.broadRoomAllControllersInclude(room, msg);
	}

	@Override
	public void gameOver(Room room) {
		//小结算
		smallCalculate(room);		
	}

	private void smallCalculate(Room room) {
		//开始小结算数据计算
		int room_times=room.getRoom_times();
		DnRoomCache dnRoomCache = (DnRoomCache) room.getRoomCache();
		DnGameBase dnGameBase = (DnGameBase) room.getGameBase();
		DnConfig dnConfig = (DnConfig) room.getGameConfig();
		dnRoomCache.setLast_banker_uid(dnGameBase.getBanker_uid());
		
		//小结算
		calculateSmallPanel(room);

		//处理淘汰玩家
		taotai(room);
		
		LogicUtil.broadRoomAllControllersInclude(room, Message.build(DNCMD.NOTIFY_SMALL_CALCULATE, Resp.build(Code.OK, "小结算数据",PckUtil.packageNotifySmallCalculate(room))));
		
		//如果当前房间剩余的非淘汰玩家小于等于一个了则提前进行大结算
		int size=room.getControllersWithoutTaotai().size();
		boolean advance_big_calculate=size<=1?true:false;
		int total_times=dnConfig.getTotal_times();
		if(advance_big_calculate||room_times>=total_times) {
			bigCalculate(room,BigCalSource.SMALLOVER_BIG_CAL);
		}else {
			smallCalculateReset(room);
		}
	}

	private void taotai(Room room) {
		DnGameBase dnGameBase = (DnGameBase) room.getGameBase();
		DnRoomCache dnRoomCache = (DnRoomCache) room.getRoomCache();
		for(PlayerData playerData:dnGameBase.getPlayers().values()) {
			int uid=playerData.getUid();
			LogicController logicController = room.getControllersWithoutWatcherAndTaotai().get(uid);
			if(!RoomUtil.checkMoneyEnoughNextRound(room, logicController)) {
				System.out.println("玩家钱包不够了加入到淘汰列表了:"+uid);
				dnRoomCache.getTaotais().add(uid);
			}
		}
	}

	private void calculateSmallPanel(Room room) {
		int room_times=room.getRoom_times();
		DnRoomCache dnRoomCache = (DnRoomCache) room.getRoomCache();
		DnSmallPanel dnSmallPanel = (DnSmallPanel) dnRoomCache.getSmallPanels().get(room_times);
		dnSmallPanel.setGameOverTime(System.currentTimeMillis());
		List<PlayerSmallCal> playerCals=smallCalScoreBegin(room);
		dnSmallPanel.getPlayerCals().addAll(playerCals);				
	}

	private Map<Integer,Integer> scoreMap(Room room) {
		Map<Integer,Integer> scoreMap=new HashMap<Integer, Integer>();
		DnRoomCache dnRoomCache = (DnRoomCache) room.getRoomCache();
		DnGameBase dnGameBase = (DnGameBase) room.getGameBase();
		DnMultiple dnMultiple = dnRoomCache.getDn_multiple();
		//开始比较大小
		PlayerData banker_data=dnGameBase.getPlayers().get(dnGameBase.getBanker_uid());
		int qiangzhuang_multiple=banker_data.getQiangzhuang_multiple();//抢庄倍数
		int banker_uid=banker_data.getUid();
		int banker_win_score=0;
		for(PlayerData playerData :dnGameBase.getPlayers().values()) {
			int uid=playerData.getUid();
			if(uid!=banker_uid) {
				int bs0=dnMultiple.getDn_multiple().get(banker_data.getDnOut().getNiu());//庄家倍数
				int bs1=dnMultiple.getDn_multiple().get(playerData.getDnOut().getNiu());//玩家倍数
				int yazhu_multiple=playerData.getYazhu_multiple();//压注倍数
				//与庄家比较
				if(playerData.getDnOut().getNiu()<banker_data.getDnOut().getNiu()) {
					//庄家赢
					int niu_x=bs0;
					int lose_score=qiangzhuang_multiple*yazhu_multiple*niu_x;
					banker_win_score+=lose_score;//庄家赢
					scoreMap.put(uid, -lose_score);//玩家输
				}else if(playerData.getDnOut().getNiu()>banker_data.getDnOut().getNiu()) {
					//玩家赢
					int niu_x=bs1;
					int win_score=qiangzhuang_multiple*yazhu_multiple*niu_x;
					banker_win_score-=win_score;//庄家输
					scoreMap.put(uid, win_score);//玩家赢
				}else {
					//牛相同,比较最大牌,最大牌相同比较最大牌花色
					int win_uid=CardUtil.compareMaxCard(banker_data,playerData);
					if(win_uid==uid) {
						//玩家赢
						int niu_x=bs1;
						int win_score=qiangzhuang_multiple*yazhu_multiple*niu_x;
						banker_win_score-=win_score;//庄家输
						scoreMap.put(uid, win_score);//玩家赢
					}else {
						//庄家赢
						int niu_x=bs0;
						int lose_score=qiangzhuang_multiple*yazhu_multiple*niu_x;
						banker_win_score+=lose_score;//庄家赢
						scoreMap.put(uid, -lose_score);//玩家输
					}
				}
			}
		}
		scoreMap.put(banker_uid, banker_win_score);		
		return scoreMap;
	}

	private List<PlayerSmallCal> smallCalScoreBegin(Room room) {
		List<PlayerSmallCal> list=new ArrayList<>();
		Map<Integer,Integer> scoreMap=scoreMap(room);
		DnConfig dnConfig = (DnConfig) room.getGameConfig();
		DnGameBase dnGameBase= (DnGameBase) room.getGameBase();
		for(PlayerData playerData:dnGameBase.getPlayers().values()) {
			int uid=playerData.getUid();
			int cur_win_score=scoreMap.get(uid);
			long base_score=dnConfig.getBase_score();
			long cur_win_gold=cur_win_score*base_score;
			LogicController logicController = room.getAllControllers().get(uid);
			
			//计算玩家分数
			long old_win_gold=logicController.getWin();
			long old_gold=logicController.getGold();
			logicController.setWin(old_win_gold+cur_win_gold);
			logicController.setGold(old_gold+cur_win_gold);
			
			PlayerSmallCal playerSmallCal = new PlayerSmallCal();
			playerSmallCal.setSimpleUser(logicController.getSimpleUser());
			playerSmallCal.getHands().addAll(playerData.getDnOut().getCards());
			playerSmallCal.setNiu(playerData.getDnOut().getNiu());
			playerSmallCal.setCur_win_score(cur_win_score);
			playerSmallCal.setCur_win_gold(cur_win_gold);
			playerSmallCal.setTotal_win_gold(logicController.getWin());
			playerSmallCal.setLeft_gold(logicController.getGold());
			list.add(playerSmallCal);
		}
		return list;
	}

	private void smallCalculateReset(Room room) {
		PlaybackUtil.saveClubSmallPlayback(room);
		room.setRoom_status(RoomStatus.WAIT_NEXT_ROUND);
		String room_id=room.getRoom_id();
		DnGameBase dnGameBase =new DnGameBase(room_id);
		room.setGameBase(dnGameBase);	
		DnTimer dnTimer = new DnTimer(room_id);
		room.setTimer(dnTimer);
		RoomCache roomCache = room.getRoomCache();
		roomCache.getWatchers().clear();//清除观战者
		LogicUtil.broadRoomAllControllersInclude(room, Message.build(DNCMD.NOTIFY_SMALL_RESET, Resp.build(Code.OK, "小结算重置消息",PckUtil.packageNotifySmallReset(room))));
	}

	@Override
	public void bigCalculate(Room room,int source) {
		room.setRoom_status(RoomStatus.CALCULATING);
		WorkManager.getManager().submit(GameOverCalculateSyncWork.class,room,source);
	}

	@Override
	public void reqQiangzhuang(Room room, LogicController controller, int multiple) {
		int room_status=room.getRoom_status();
		if(room_status!=DnRoomStatus.QIANGZHUANG) {
			//当前不在抢庄状态了
			controller.getWebClient().sendMessage(Message.build(DNCMD.RES_QIANGZHUANG,Resp.build(Code.CANT_QIANGZHUANG,"当前不能抢庄")));
			return;
		}
		DnGameBase dnGameBase = (DnGameBase) room.getGameBase();
		int uid=controller.getId();
		PlayerData playerData = dnGameBase.getPlayers().get(uid);
		
		if(playerData.getQiangzhuang_multiple()!=null) {
			//已经抢过了
			return;
		}
		
		int max_multiple=playerData.getQiangzhuang_max_multiple();
		if(multiple<0||multiple>max_multiple) {
			controller.getWebClient().sendMessage(Message.build(DNCMD.RES_QIANGZHUANG,Resp.build(Code.PARAM_ERROR,"抢庄参数错误")));
			return;
		}
		if(multiple==0) {
			//不抢
			playerData.setBuqiang(true);
			playerData.setQiangzhuang_multiple(1);
		}else {
			playerData.setQiangzhuang_multiple(multiple);
		}
		controller.getWebClient().sendMessage(Message.build(DNCMD.RES_QIANGZHUANG, Resp.build(Code.OK, "抢庄成功",PackageUtil.packageResQiangzhuang(uid,multiple))));
		LogicUtil.broadRoomAllControllersInclude(room, Message.build(DNCMD.NOTIFY_SOMEONE_QIANGZHUANG, Resp.build(Code.OK, "通知抢庄",PackageUtil.packageNotifyQiangzhuang(uid,multiple))),controller);
	}

	@Override
	public void reqYazhu(Room room, LogicController controller, int multiple) {
		int room_status=room.getRoom_status();
		if(room_status!=DnRoomStatus.YAZHU) {
			//当前不在抢庄状态了
			controller.getWebClient().sendMessage(Message.build(DNCMD.RES_YAZHU,Resp.build(Code.CANT_YAZHU,"当前不能压注")));
			return;
		}
		DnGameBase dnGameBase = (DnGameBase) room.getGameBase();
		int uid=controller.getId();
		int banker_uid=dnGameBase.getBanker_uid();
		if(uid==banker_uid) {
			//庄家不能压注
			return;
		}
		PlayerData playerData = dnGameBase.getPlayers().get(uid);
		if(playerData.getYazhu_multiple()!=null) {
			//已经压注过了
			return;
		}
		int max_multiple=playerData.getYazhu_max_multiple();
		if(multiple<1||multiple>max_multiple) {
			controller.getWebClient().sendMessage(Message.build(DNCMD.RES_YAZHU,Resp.build(Code.PARAM_ERROR,"压注参数错误")));
			return;
		}
		playerData.setYazhu_multiple(multiple);
		controller.getWebClient().sendMessage(Message.build(DNCMD.RES_YAZHU, Resp.build(Code.OK, "压注成功",PackageUtil.packageResYazhu(uid,multiple))));
		LogicUtil.broadRoomAllControllersInclude(room, Message.build(DNCMD.NOTIFY_SOMEONE_YAZHU, Resp.build(Code.OK, "通知压注",PackageUtil.packageNotifyYazhu(uid,multiple))),controller);
	}

	@Override
	public void reqLiangpai(Room room, LogicController controller) {
		int room_status=room.getRoom_status();
		if(room_status!=DnRoomStatus.LIANGPAI) {
			//当前不在抢庄状态了
			controller.getWebClient().sendMessage(Message.build(DNCMD.RES_LIANGPAI,Resp.build(Code.CANT_LIANGPAI,"当前不能亮牌")));
			return;
		}
		
		DnGameBase dnGameBase = (DnGameBase) room.getGameBase();
		int uid=controller.getId();
		PlayerData playerData = dnGameBase.getPlayers().get(uid);
		if(playerData.getLiangpai()!=null) {
			//已经亮过牌了
			return;
		}
		playerData.setLiangpai(true);
		DnOut dnOut = playerData.getDnOut();
		controller.getWebClient().sendMessage(Message.build(DNCMD.RES_LIANGPAI, Resp.build(Code.OK, "亮牌成功",PackageUtil.packageResLiangpai(uid,dnOut))));
		LogicUtil.broadRoomAllControllersInclude(room, Message.build(DNCMD.NOTIFY_SOMEONE_LIANGPAI, Resp.build(Code.OK, "通知亮牌",PackageUtil.packageNotifyLiangpai(uid,dnOut))),controller);
	}

	@Override
	public void reqSetcards(Room room, LogicController controller, List<Integer> cardIds) {
		DnRoomCache dnRoomCache = (DnRoomCache) room.getRoomCache();
		SetcardsPanel setcardsPanel = dnRoomCache.getSetcardsPanel();
		Map<Integer,List<Integer>> setsmap=setcardsPanel.getSetsmap();
		if(cardIds.size()!=5) {
			//15张
			controller.getWebClient().sendMessage(Message.build(DNCMD.RES_SETCARDS, Resp.build(Code.PARAM_ERROR, "必须5张")));
			return;
		}
		List<Card> deck=new ArrayList<>();
		deck.addAll(CardUtil.deckWithoutJoker());
		List<Integer> allcardIds=new ArrayList<>();
		for(Card card:deck) {
			allcardIds.add(card.getCardId());
		}
		boolean allhas=allcardIds.containsAll(cardIds);
		if(!allhas) {
			controller.getWebClient().sendMessage(Message.build(DNCMD.RES_SETCARDS, Resp.build(Code.PARAM_ERROR, "存在找不到的牌id")));
			return;
		}
		boolean repeated=false;
		for(List<Integer> tmp:setsmap.values()) {
			for(Integer cardId:cardIds) {
				if(tmp.contains(cardId)) {
					//重复了
					repeated=true;
					break;
				}
			}
			if(repeated) {
				break;
			}
		}
		
		if(repeated) {
			//牌设置重复了,返回最新的牌组给客户端
			for(List<Integer> tmp:setsmap.values()) {
				allcardIds.removeAll(tmp);
			}
			controller.getWebClient().sendMessage(Message.build(DNCMD.RES_SETCARDS, Resp.build(Code.PARAM_ERROR, "剩余牌错误",PackageUtil.packageResSetcards(allcardIds))));
			return;
		}
		
		setsmap.put(controller.getId(), cardIds);
		controller.getWebClient().sendMessage(Message.build(DNCMD.RES_SETCARDS, Resp.build(Code.OK, "设置牌成功,下局生效")));
	}

	@Override
	public void reqSetcardsLeft(Room room, LogicController controller) {
		DnRoomCache dnRoomCache = (DnRoomCache) room.getRoomCache();
		List<Card> deck=new ArrayList<>();
		deck.addAll(CardUtil.deckWithoutJoker());
		SetcardsPanel setcardsPanel = dnRoomCache.getSetcardsPanel();
		Map<Integer,List<Integer>> setsmap=setcardsPanel.getSetsmap();
		List<Integer> list=new ArrayList<>();
		for(List<Integer> tmp:setsmap.values()) {
			list.addAll(tmp);
		}
		List<Integer> all=new ArrayList<>();
		for(Card card:deck) {
			all.add(card.getCardId());
		}
		all.removeAll(list);
		controller.getWebClient().sendMessage(Message.build(DNCMD.RES_SETCARDS_LEFT, Resp.build(Code.OK, "拉取余下的牌成功",PackageUtil.packageResSetcardsLeft(all))));
	}

	@Override
	public void reqKanpai(Room room, LogicController controller) {
		int room_status=room.getRoom_status();
		if(room_status!=DnRoomStatus.YAZHU&&room_status!=DnRoomStatus.LIANGPAI) {
			//当前不在压注或者亮牌状态了
			controller.getWebClient().sendMessage(Message.build(DNCMD.RES_KANPAI,Resp.build(Code.CANT_KANPAI,"当前不能看牌")));
			return;
		}
		DnGameBase dnGameBase = (DnGameBase) room.getGameBase();
		int uid=controller.getId();
		int banker_uid=dnGameBase.getBanker_uid();
		PlayerData playerData = dnGameBase.getPlayers().get(uid);
		if(uid!=banker_uid) {
			//庄家可以直接看牌,闲家必须先压注
			if(playerData.getYazhu_multiple()==null) {
				//还未压过注
				controller.getWebClient().sendMessage(Message.build(DNCMD.RES_KANPAI,Resp.build(Code.CANT_KANPAI,"当前不能看牌")));
				return;
			}
		}
		playerData.setKanpai(true);
		DnOut dnOut = playerData.getDnOut();
		controller.getWebClient().sendMessage(Message.build(DNCMD.RES_KANPAI, Resp.build(Code.OK, "看牌成功",PackageUtil.packageResLiangpai(uid,dnOut))));
	}

}
